
; >FileCore00

        TTL     "Start of module, declarations and workspace allocation"

        LEADR   Module_LoadAddr
org
Module_BaseAddr

;Module Header
        ASSERT  {PC}-org=0
        & 0                     ;no start entry
        & InitEntry       - org ;initialisation entry
        & DieEntry        - org
        & ServiceEntry    - org
        & Title           - org
        & HelpString      - org
        & ComTab          - org
FileCoreSwiBase * Module_SWISystemBase + FileCoreSWI * Module_SWIChunkSize
        & FileCoreSwiBase
        & SwiEntry        - org
        & SwiNames        - org
        & 0                     ;no SWI name decoding code
 [ International_Help <> 0
        & message_filename - org
 |
        & 0
 ]
        ASSERT  {PC}-org=48

Title
        Text    "FileCore"


HelpString
        =       "FileCore",9
        [ Dev
        =       DevVersion," DEVELOPMENT VERSION"
        |
        =       Module_MajorVersion," (",Module_Date,")"
        ]
anull   = 0
        ALIGN

        LTORG
        GET     s.Errors

; Disc Record

        ^ 0
;
SectorSize      # 1     ;log2 sector size
SecsPerTrk      # 1
Heads           # 1     ;n-1 for old adfs floppy format
Density         # 1     ;1/2/4 single double quad

;only those above & DiscsDrv & Disc Size needed for low level drivers

        [ NewFs
LinkBits        # 1
BitSize         # 1     ;log2 bytes for each bit in map, 0 for old format
RAskew          # 1     ;track to track sector skew for random access
        |               ;file allocation
                # 3
        ]
BootOpt         # 1     ;boot option for this disc

        [ NewFs
 [ Module_Version >= 205
LowSector       # 1     ; Lowest sector number on a track and flags:
                ; Bit     Meaning when set
LowSectorMask   * &3f
                ; 0-5     Lowest numbered sector on a track
SequenceSides   bit 6
                ; 6       Tracks are numbered 0..s-1 on side 0, then s..2s-1 on side 1, etc
DoubleStep      bit 7
                ; 7       Double step

 |
                # 1
 ]
Zones           # 1     ;# zones in map
ZoneSpare       # 2     ;# bits in zones after 0 which are not map bits
        ASSERT  (ZoneSpare :MOD: 4)=2
        |
                # 4
        ]
RootDir         aw 4
DiscSize        aw 4

DiscStruc       # 0     ;above entries (except BootOpt) define disc structure

DiscId          aw 2
DiscName        # 10
DiscRecSig      # 0     ;above entries form signature of disc

DiscType        aw 4    ; FileType of disc: FileType_Data indicates
                        ; that the disc is, as yet, unidentified.
                        ; This may occur as a result of the identification
                        ; process failing, or the identification process
                        ; not yet happening. FileType_Data discs have no
                        ; concept of a unique identifier so drive independance
                        ; when accessing them is not possible.

 [ BigDisc
DiscSize2	aw 4	; top 32bits of the disc size.  This combines with
			; DiscSize to give the full size of the disc.  Note
			; that we may have to move DiscStruc to below here
			; so we can compare structures properly.
 [ BigShare
ShareSize       # 1     ; sharing unit
BigFlag         # 1     ; flag - 0 for small disc, 1 for big
SharePad        # 2     ; padding
 ]
DiscRecSig2      # 0     ;above entries form signature of disc
 ]
DiscFlags       # 1
FloppyFlag              bit 0
NeedNewIdFlag           bit 1   ; Indicates that when this disc is next updated a new Id aught to be given it too
DiscNotFileCore         bit 2   ; Indicates this isn't a FileCore disc (yet)
DiscNotIdentified       bit 3   ; Indicates this Data disc hasn't been identified as something else yet.
        [ NewFs
AltMapFlag              bit 5
OldMapFlag              bit 6
        |
OldMapFlag              * 0
        ]
OldDirFlag              bit 7   ;set <=> old small dirs


;entries below must be valid even when disc rec is not in use
Priority        # 1     ;0 DISC REC UNUSED
                        ;1 to # floppies -> floppy priority level
                        ;&FF good winnie
DiscsDrv        # 1     ;0-7 => drive in, 8 => not in drive, OR DISC REC UNUSED
DiscUsage       # 1     ;tasks using this disc, if >0 disc cant be forgotten
SzDiscRec       # 0

;default last word of disc record
;DiscFlags      0  FLOPPIES NEED NeedNewIdFlag SET INITIALLY
;Priority       0
;DiscsDrv       8
;DiscUsage      0
DefDiscRecEnd   * &00080000

; Preamble to disc rec for FORMAT
SzFormHdr * 8
        ^ -SzFormHdr
FormSig         # 1     ;signature
FormChar        # 1
HalfSide0Gap1   # 1
HalfSide1Gap1   # 1
Gap3            # 1
Skew            # 1
                # 2     ;unused
        ASSERT @=0
SzFormDiscRec   * SzDiscRec+SzFormHdr

L_Root          * &200
D_Root          * &400

L_Size          * 640*K
D_Size          * 800*K

        [ NewFs
NewMapRoot              * &203   ;indirect disc add
NewFloppyRootDiscAdd    * &800   ;physical disc add
        ]

;point Rptr to start of disc record Rindex, must preserve flags
        MACRO
$lab    DiscRecPtr $Rptr,$Rindex,$cond
        ASSERT  $Rptr<>SB
        ASSERT  $Rptr<>PC
 [ BigDisc
 [ DebugDR
        Push    "SB,LR, R0"
        MOV     R0, $Rindex
        MOV     SB, PC
        BICS    LR, R0, #7
        BEQ     %FT01
        DREG    R0, "DiscRecPtr: illegal disc:"
        DREG    PC, "PC:"
01
        TEQP    PC,SB
        MOV     R0,R0
        Pull    "SB,LR,R0"
 ]
  [ BigShare
	ASSERT	SzDiscRec=48
	ADD$cond $Rptr, $Rindex, $Rindex, ASL #1 ;*3
        ADD$cond $Rptr,SB,$Rptr,ASL #4           ;SB+Rindex*SzDiscRec
  |
	ASSERT	SzDiscRec=44
   [ $Rptr<>$Rindex
	ADD$cond $Rptr, $Rindex, $Rindex, ASL #1 ;*3
	ADD$cond $Rptr, $Rptr, $Rindex, ASL #3	 ;+*8=*11
	ADD$cond $Rptr, SB, $Rptr, ASL #2	 ;SB+Rindex*SzDiscRec
   |
	Push	"SB"
	ADD$cond SB, $Rindex, $Rindex, ASL #1	 ;*3
	ADD$cond $Rptr, SB, $Rindex, ASL #3	 ;+*8=*11
	Pull	"SB"
	ADD$cond $Rptr, SB, $Rptr, ASL #2	 ;SB+Rindex*SzDiscRec
   ]
  ]
 |
 [ Module_Version >= 205
        ASSERT  SzDiscRec=40
        ADD$cond $Rptr,$Rindex,$Rindex,ASL #2   ;*5
        ADD$cond $Rptr,SB,$Rptr,ASL #3          ;SB+Rindex*SzDiscRec
 |
        ASSERT  SzDiscRec=36
        ADD$cond $Rptr,$Rindex,$Rindex,ASL #3   ;*9
        ADD$cond $Rptr,SB,$Rptr,ASL #2          ;SB+Rindex*SzDiscRec
 ]
 ]
        MinOps  ADD, ADD, $Rptr, $Rptr, (:INDEX:DiscRecs), $cond
        MEND

; Changes to Disc Record structure also affect
;  InitRdFloppyFs - Adfs20

; Drive Record

        ^ 0
DrvsDisc        # 1
Uncertain       bit 7   ; Contents of disc in drive uncertain - may have a disc record attached, but not certain it's the right one or that it's type is correct
Unknown         bit 6   ; Contents of disc in drive not known (no attached disc record)
Empty           bit 5   ; Disc definitely not in drive
Full            bit 4   ; Disc definitely in drive, but no disc record attached to drive

DrvFlags        # 1     ; Flags about drive
HasDefectList   bit 0   ; Set if drive has a defect list
LastDiscOpWasFormat bit 1 ; Set if the last DiscOp was a format track operation
LockCount       # 1     ; How many times the drive's been locked
PrevFormSectorSize # 1  ; SectorSize in previous format operation
PrevFormSecsPerTrk # 1  ; SecsPerTrk in previous format operation
PrevFormHeads   # 1     ; Heads in previous format operation
PrevFormDensity # 1     ; Density in previous format operation
PrevFormLowSector # 1   ; LowSector in previous format operation
PrevFormDiscSize aw 4   ; DiscSize in previous format operation
 [ BigDisc
PrevFormDiscSize2 aw 4  ; 2nd part of DiscSize in previous format operation
 ]
ChangedSeqNum   aw 4
DrvsFsMap aw 4  ;ptr to free space maps
BadFs   bit 31  ;set if corrupt on disc
EmptyFs bit 30  ;set if FS map buffer empty for old maps
HiFsBits        * BadFs :OR: EmptyFs
SzDrvRec        # 0


;point Rptr to start of drive record Rindex, must preserve flags
        MACRO
$lab    DrvRecPtr $Rptr,$Rindex,$cond
        ASSERT  $Rptr<>SB
        ASSERT  $Rptr<>PC
 [ BigDisc
        ASSERT  SzDrvRec=24
 [ DebugDR
        Push    "SB,LR, R0"
        MOV     R0, $Rindex
        MOV     SB, PC
        BICS    LR, R0, #7
        BEQ     %FT01
        DREG    R0, "DrvRecPtr: illegal disc:"
        DREG    PC, "PC:"
01
        TEQP    PC,SB
        MOV     R0,R0
        Pull    "SB,LR,R0"
 ]
        ADD$cond $Rptr,$Rindex,$Rindex,LSL #1
        ADD$cond $Rptr,SB,$Rptr,LSL#3
 |
        ASSERT  SzDrvRec=20
        ADD$cond $Rptr,$Rindex,$Rindex,LSL #2
        ADD$cond $Rptr,SB,$Rptr,LSL#2
 ]
        MinOps  ADD, ADD, $Rptr, $Rptr, (:INDEX:DrvRecs), $cond
        MEND


; structure of dir cache obj

                ^ 0
CacheNext       aw 4    ;->next obj, -1 marks end of cache
CachePriority   aw 4    ;0 for free space, -1 marks end of cache
CacheMin        # 0     ;min size for free space

; rest dont apply to free spaces
CacheRootStart  # 0
CacheYounger    aw 4    ;-> next youngest dir
CacheOlder      aw 4    ;-> next oldest dir
CacheRootEnd    # 0

CacheDir        aw 4    ;disc address of dir
CacheBody       # 0


 [ Module_Version >= 205
; structure of a sector cache entry

                        ^ 0
SectorCache_Next        aw 4    ; Link to next cached sector, or 0
SectorCache_Address     aw 4    ; disc address of this cached sector
SectorCache_Error       aw 4    ; error encountered when reading this sector
SectorCache_Usage       aw 4    ; Number of times this block's been used
SectorCache_HeaderSize  # 0
SectorCache_Contents    # 0
 ]

; DEFECT LIST

; The list consists of words containing the disc address ( in bytes ) of bad
; sectors, the end is marked by a value &200000xx, where &xx forms a check
; byte on the earlier list. The last 64 bytes describe the disc to FileCore.
; Any other bytes may be used as params for the low level drivers

DefectListDiscAdd       * &400+&800
SzDefectList            * &200
DefectEndMark           bit 29
MaxStruc                * 64
        ASSERT  SzDiscRec<=MaxStruc

        ^ 0
                # SzDefectList-MaxStruc-4
ParkDiscAdd     # 4
DefectStruc     # MaxStruc-1
;DefectCheck
                # 1
        ASSERT  @=SzDefectList


; OLD FS MAP
        ^ 0
FreeStart       # 82*3  ;table of free space start sectors
EndSpaceList    # 0
                # 1     ;reserved
OldName0        # 5     ;              RETRO DEFINITION
OldSize         # 3     ;size in sectors
Check0          # 1     ;checksum on sector 0

FreeLen         # 82*3  ;table of free space lengths
OldName1        # 5     ;              RETRO DEFINITION
OldId           # 2     ;disc id
OldBoot         # 1     ;boot option
FreeEnd         # 1     ;ptr to end of free space list
Check1          # 1     ;checksum on sector 1

        ASSERT  {VAR}=&200

        [ NewFs
; New map

                ^ 0
ZoneCheck       # 1
FreeLink        # 2     ;15 bit free space start link
CrossCheck      # 1     ;EORing this byte for all zones should yield &FF

DummyLenBit     bit 31  ;always set

ZoneDiscRecSz   * 60    ;reserve additional bytes
                ASSERT ZoneDiscRecSz>=SzDiscRec

ZoneHead        # ZoneDiscRecSz

Zone0Bits       * ZoneDiscRecSz*8

;zones are followed in RAM by table of one byte of flags per zone

ZoneValid       bit 0
ZoneCompacted   bit 1

        ]


; Dir entry
                ^ 0
NameLen         * 10
DirObName       # NameLen
DirLoad         # 4
DirExec         # 4
DirLen          # 4
DirIndDiscAdd   # 3
OldDirObSeq     # 1

OldDirEntrySz   * {VAR}
        ASSERT  OldDirEntrySz=26

NewDirAtts      * OldDirObSeq
ReadBit         bit 0
WriteBit        bit 1
IntLockedBit    bit 2   ;the locked bit is held in bit 2 internally
ExtLockedBit    bit 3   ;but is returned in bit 3 externally
DirBit          bit 3
EBit            bit 4   ;6502 ADFS E files are treated as if R
 [ FullAtts             ;extended attributes only for new dirs
Att4            bit 4
PublicReadBit   * Att4
Att5            bit 5
PublicWriteBit  * Att5
Att6            bit 6
Att7            bit 7
NewAtts         * Att4 :OR: Att5 :OR: Att6 :OR: Att7
 |
NewAtts         * 0
 ]
IntDirAttMask   * IntLockedBit :OR: DirBit :OR: NewAtts
IntAttMask      * IntDirAttMask :OR: ReadBit :OR: WriteBit
ExtAttMask      * ReadBit :OR: WriteBit :OR: ExtLockedBit :OR: NewAtts

NewDirEntrySz   * {VAR}


; Directory Start
                ^ 0
StartMasSeq     # 1
StartName       # 4
DirFirstEntry   # 0

; Old Directory End
                ^ 0
                # -1
DirCheckByte    # 0     ;RETRO DEFINITION was reserved

                # -4
EndName         # 0

                # -1
EndMasSeq       # 0

                # -14   ;reserved

DirTitleSz      * 19
                # -DirTitleSz
OldDirTitle     # 0

                # -3
OldDirParent    # 0

                # -NameLen
OldDirName      # 0

                # -1
OldDirLastMark  # 0     ;dummy last entry marker

; New Directory End
                ^ 0
                # -1
        ASSERT  DirCheckByte=@

                # -4
        ASSERT  EndName=@

                # -1
        ASSERT  EndMasSeq=@

                # -NameLen
NewDirName      # 0

                # -DirTitleSz
NewDirTitle     # 0

                # -3
NewDirParent    # 0

                # -1    ;reserved
                # -1    ;reserved

                # -1
NewDirLastMark  # 0     ;dummy last entry marker

OldDirSize      * &500
NewDirSize      * &800

OldDirTabSz     * (OldDirSize-DirFirstEntry+OldDirLastMark)
NewDirTabSz     * (NewDirSize-DirFirstEntry+NewDirLastMark)
                ASSERT  OldDirTabSz :MOD: OldDirEntrySz = 0
                ASSERT  NewDirTabSz :MOD: NewDirEntrySz = 0
OldDirEntries   * OldDirTabSz / OldDirEntrySz
NewDirEntries   * NewDirTabSz / NewDirEntrySz

        ASSERT  OldDirEntries=47
        ASSERT  NewDirEntries=77


 [ FileCache

BufSz           RN 4
FileOff         RN 5
DiscAdjust      RN 6
TransferEnd     RN 7
FragEnd         RN 8
Fcb             RN 9
BufOff          RN 10
BufPtr          RN 11

;FILE CACHE BUFFER
                ^ 0

BufFlags        # 4     ;these 4 are in common with extended FCB
NextInFile      # 4
PrevInFile      # 4
BufFileOff      # 4

BufFcb          # 4
OlderBuf        # 4
YoungerBuf      # 4
BufPriority     # 1
                # 3
BufferData      # 1*K   ;data itself

BufScale        * 5
                ASSERT BufferData :SHL: BufScale = 1*K

                ^ 0                     ;priority levels for buffers
EmptyChain      # 1
MonotonicChain  # 1
NormalChain     # 1
AwaitsSeqChain  # 1
ReadAheadChain  # 1
WriteBehindChain # 1

EmptyBuf        bit EmptyChain+2        ;priority level flags
UsedMonotonic   bit MonotonicChain+2
NormalBuf       bit NormalChain+2
AwaitsSeqRead   bit AwaitsSeqChain+2
ReadAhead       bit ReadAheadChain+2
WriteBehind     bit WriteBehindChain+2

AllocFlags      * EmptyBuf :OR: UsedMonotonic :OR: NormalBuf :OR:AwaitsSeqRead :OR: ReadAhead :OR: WriteBehind
                ASSERT AllocFlags=2_11111100

 ]

; File Control Block

        ^ 0
 [ FileCache    ;FCB has header in common with file cache buffer

 ASSERT BufFlags=@
 #      4
 ASSERT NextInFile=@
 #      4
 ASSERT PrevInFile=@
 #      4
 ASSERT BufFileOff=@
 #      4

 ]

FcbNext         aw 4    ;link to next FCB
FcbFlags        # 1
FcbBufSz        # 1
FcbName         # 10
FcbLength       aw 4    ;ASSUME LOWEST BYTE ZERO TO USE AS NAME TERMINATOR
FcbDir          aw 4    ;dir containing file
FcbIndDiscAdd   aw 4
FcbExtent       aw 4
FcbExtHandle    # 4     ;0             => Fcb kept around although file closed
NotHandle       * 32*K  ;1-NotHandle-1 => external handle and access<>R
                        ;>=NotHandle   => ptr to chain of external handles
 [ FileCache
LastReadEnd     # 4
AccessHWM       # 4
ReadAheadBufs   # 1
DataLostFlag    # 1
                # 1
                # 1
 ]
FcbSize         # 0

; Flags
; b0 set <=> file has read access
; b1 set <=> file has write access
 [ FileCache
; b2 Indicates which controller
FcbFloppyBitNo  * 2
FcbFloppyFlag   bit FcbFloppyBitNo
 ]
; b3 set <=> dir
; b4 set <=> EXT needs ensuring
                ASSERT  ReadBit  = bit0
                ASSERT  WriteBit = bit1
                ASSERT  DirBit   = bit3
ExtFlag         bit 4
 [ FileCache
Monotonic       bit 5   ;set <=> all read access above HWM
SequentialBitNo * 6
Sequential      bit SequentialBitNo     ;set <=> reading sequentially
 ]
 [ Module_Version >= 205
FcbDiscImage    bit 7   ; set <=> Fcb is disc image
 ]

;object in handle chain if can be multiply open

                ^ 0
NextHandleBlk   # 4
HandleBlkFcb    # 4
ExtHandle       # 4
HandleBlkSize   # 0

HandleBlkBit    bit 31  ;bit that marks internal handle as ptr to handle block

 [ FileCache

;Background process control block
;Both floppies and winnies have values of following

                ^ 0
Process         # 1     ;AMENDED FROM INACTIVE BY RETRYDRIVEOP
Inactive        bit 0
                ASSERT ReadAhead   = bit6
                ASSERT WriteBehind = bit7
ProcessDirect   # 1     ;0/&FF if process includes a direct transfer
ProcessDrive    # 1     ;FILLED IN BY RETRYDRIVEOP
                # 1
ShortProcessBlk # 0     ;when file cache not in use

ProcessEndPtr   # 4
OldLength       # 4
 [ WinniesAsFloppies
ProcessWriteBehindDrive # 1     ;Must be in same word for atomic write
ProcessWriteBehindDisc # 1
                # 2     ;Not free for other use
ProcessWriteBehindLeft # 4
 ]
ProcessStartPtr # 4     ;DO NOT REORDER THESE
ProcessRamAdjust # 4
ProcessStartOff # 4
ProcessEndOff   # 4
ProcessFragEnd  # 4
ProcessFcb      # 4
ProcessError    # 4
ProcessStatus   # 4
Active          bit 31
CanExtend       bit 30
ProcessPairs    # 0

ExtraPairs      * 2

 ]

; WORKSPACE ALLOCATION

;
; -----------------------------------------------------------------------------
; | misc. | Dir    | Directory cache : Random access     | winnie and 'floppy'
; | work  | Buffer |                 : file buffer cache | defect
; | space |        |                 :                   | lists
; -----------------------------------------------------------------------------
; ^0                                 ^ FileBufsStart     ^DefectSpace
;

; ALL POINTERS TO WORKSPACE NEEDING TO BE PRESERVED OVER TIDY MUST BE
; WORKSPACE RELATIVE

        ^ 0,SB
PrivateWord     # 4     ;back ptr to private word ;MUST BE FIRST
DefectSpace     # 4     ;workspace relative

;Globals that get initialised


DefGlobals
DefGlobStart    # 0

ReEntrance      # 1     ;bit  5 set => no reentrance
        = 1             ;bits 0-4
; 0 => dormant
; 1 => executing first incarnation
; 2 => doing MOS call for first incarnation
; 3 => executing reentered code
; 4 => doing MOS call for reentered code
NoReEnterBit    bit 6
LastReEnter     # 1     ;set non zero whenever FileCore entered
        = 0
ScatterEntries  # 1     ;# chunks claimed for data move scatter block
        = 0
Flags           # 1
        = 0
CacheGood      bit 7
TruncateNames  bit 4    ; 0 means truncate, 1 means barf (yup, its the other way round to what's in CMOS)

 [ :LNOT: FileCache
LockedDrive     # 1
        = &FF
FiqOwnership    # 1
        = 0
                # 2
        = 0,0
 ]

; MessageTrans open flag
message_file_open       a4 4
        & 0

UserRootDir     a4 4
        & -1
LibDir          a4 4
        & -1
CurDir          a4 4
        & -1
BackDir         a4 4
        & -1
CritBufDir      a4 4    ;use when BufDir itself must be invalid
        & -1
BufDir          a4 4    ;currently buffered directory
        & -1

FirstFcb        a4 4    ;link to first file control block
        & -1

        [ NewFs
FragCache       a4 0
OldLastFilePtr  a4 4
        & 0
OldLastMapPtr   a4 4
        & 0
OldLastIndDiscAdd a4 4
        & 0
LastFilePtr     a4 4
        & 0
LastMapPtr      a4 4
        & 0
LastIndDiscAdd  a4 4
        & 0
        ]

        [ FileCache

PreferredDisc           # 1     ; Disc to use after canonicalise disc name
                = &ff
Interlocks              # 1
                = NoOpenFloppy :OR: NoOpenWinnie

;DONT CHANGE THESE TWO MAKES LSR #30 TRICK WORK
WinnieLock      bit 0
FloppyLock      bit 1

;DONT CHANGE THESE TWO MAKES LSR #28 TRICK WORK
NoOpenWinnie    bit 2   ; Means: nothing open on winnie, so don't winnie BackgroundOp
NoOpenFloppy    bit 3   ; Means: nothing open on floppy, so don't floppy BackgroundOp

FileCacheLock   bit 4   ; Means: foreground is playing with the filecache, so hands off background!
DirCacheLock    bit 5
TimerLock       bit 6   ; Means: Ticker event is currently processing BackgroundOps


FiqOwnership            # 1
                = 0
BackgroundFiqLock       # 1     ;set to &FF to stop attempts to claim FIQ
                = 0

; One free space map is 'locked' at any time. When a map is locked the disc to
; which it belongs is locked in its drive. The locked map may or not be being
; modified. If being modified ModifyDisc will have the disc number in it,
; otherwise it will be &ff. When no map is being read/modified these
; map-specific values are set to &ff:
LockedDrive             # 1     ;Must be in same word for atomic write
                = &FF
LockedDisc              # 1
                = &FF
ModifyDisc              # 1     ; Disc whose map is unsafe due to being modifed or being read whilst disc is attached to drive
                = &FF
                        # 1     ;Not free for other use
                = &FF


 [ WinniesAsFloppies
 |
FloppyWriteBehindDrive  # 1     ;Must be in same word for atomic write
                = &FF
FloppyWriteBehindDisc   # 1
                = &FF
                        # 2     ;Not free for other use
                = 0,0

FloppyWriteBehindLeft   a4 4
                & Nowt
 ]

       ]

UpperCaseTable  a4 4
                & 0

SzDefGlobals * {PC}-DefGlobals
        ASSERT {VAR}-DefGlobStart=SzDefGlobals

;INFO ON PARENT MODULE

ParentBase      # 4     ;base of parent module
ParentPrivate   # 4     ;ptr to private word of parent module
Floppies        # 1     ;# floppy drives
Winnies         # 1     ;# winnie drives
Drive           # 1     ;default drive
StartUpOptions  # 1
WinnieSizes     # 4
FloppySizes     # 4     ; Must follow WinnieSizes for indexing purposes

FS_Flags        # 3
FS_Id           # 1
FS_Title        # 4     ;FOLLOWING ARE STORED AS ABSOLUTE ADDRESSES
FS_BootText     # 4
FS_LowLevel     # 4
FS_Misc         # 4

DiscOp_ByteAddr # 4

message_file_block a4 16 ; block for messagetrans

Opt1Buffer      # NameLen+1
                # 1             ; filler

                # -CacheRootStart
RootCache       a4 CacheRootEnd


ScatterPtr      a4 4  ;->Scatter block
ScatterAdd * 0
ScatterLen * 4

ScatterBlk      a4 8

;Critical subroutine management workspace

CriticalDepth   * 2     ;max levels of critical subroutine

CriticalGood1   # 1
                # 3
CriticalSP1     a4 4
CriticalStack1  a4 (CriticalDepth+1)*4

CriticalGood2   # 1
                # 3
CriticalSP2     a4 4
CriticalStack2  a4 (CriticalDepth+1)*4

CritDrvRec      a4 4
CritDiscRec     a4 4
CritResult      # 4

BreakAction     # 1
                # 3

 [ FileCache
MaxFileBuffers          # 1
UnclaimedFileBuffers    # 1
BufHashMask             # 1
WriteDisc               # 1     ;disc in use by put bytes or &FF so that floppy
                                ;write behind can't be unset if may add more
FileBufsStart           a4 4
FileBufsEnd             a4 0    ;Same as FloppyProcessBlk
FloppyProcessBlk        a4 4
WinnieProcessBlk        a4 4
BufHash                 a4 4

TickerState             # 4     ;bottom 16 bits period, top 16 bits counter


                ASSERT  YoungerBuf = OlderBuf + 4
ChainRootSz     *       2*4              ;older and younger link
BufChainsRoot           * @-OlderBuf
                        a4 6*ChainRootSz ;roots of buffer allocation lists
 [ Dev
 ! 0, "BufChainsRoot = " :CC: :STR: :INDEX: BufChainsRoot
 ]

DirectError             a4 4    ;background error in direct transfer

 ]


 [ BigDisc
; Workspace for DoCompMoves

DoCompZoneBase	#	4
 ]


;Records
DrvRecs         a4 SzDrvRec*8
DiscRecs        a4 SzDiscRec*8
 [ Dev
 ! 0, "DrvRecs = " :CC: :STR: :INDEX: DrvRecs
 ]
 [ Dev
 ! 0, "DiscRecs = " :CC: :STR: :INDEX: DiscRecs
 ]

;Data move scatter list
ScatterMax      * 8                     ;max # (address,length) pairs in buffer
ScatterListLen  * ScatterMax*(4+4)

ScatterSource   a4 ScatterMax
ScatterList     a4 ScatterListLen
ScatterCopy     a4 ScatterListLen


        ASSERT  :INDEX:{VAR}<&1000

        ASSERT NewDirSize > OldDirSize
DirBufSize      * NewDirSize
DirBuffer       a4 DirBufSize

DirCache        # 0     ;MUST BE LAST
 [ Dev
 ! 0, "DirCache = " :CC: :STR: :INDEX: DirCache
 ]

        ALIGN
        LTORG

        END
